package com.hp.gxw.controller;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hp.gxw.constant.LayTableR;
import com.hp.gxw.constant.R;
import com.hp.gxw.entity.*;
import com.hp.gxw.entity.Process;
import com.hp.gxw.service.*;
import com.hp.gxw.utils.*;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.runtime.directive.Foreach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;

import static java.util.stream.Collectors.groupingBy;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author huangping
 * @since 2023-10-30
 */
@Controller
@RequestMapping("/manage/process_price_order")
public class ProcessPriceOrderController {

    @Autowired
    private IProcessPriceOrderService iProcessPriceOrderService;

    @Autowired
    private IProcessPriceProduceService iProcessPriceProduceService;

    @Autowired
    private ICustomerService iCustomerService;

    @Autowired
    private IProductService iProductService;

    @Autowired
    private IProcessService iProcessService;

    @Autowired
    private ISysUserService iSysUserService;

    @RequestMapping("/index")
    public String index(Model model){
        model.addAttribute("customer", iCustomerService.list());
        model.addAttribute("product", iProductService.list());
        model.addAttribute("process", iProcessService.list(new LambdaQueryWrapper<Process>().eq(Process::getType, "订单")));
        return "process_price/index";
    }

    @RequestMapping("/addOrderHtml")
    public String addOrderHtml(Model model) {
        return "process_price/add_order";
    }

    @RequestMapping("/saveOrderHtml")
    public String saveProduceHtml(Model model) {
        return "process_price/save_order";
    }
    @RequestMapping("/updateOrderHtml")
    public String updateOrderHtml(Model model,String id) {
        model.addAttribute("id", id);
        return "process_price/update_order";
    }

    @RequestMapping("/info_order")
    @ResponseBody
    public Object info_order(String id) {
        return iProcessPriceOrderService.getById(id);
    }

    @RequestMapping("/addProduceHtml")
    public String addProduceHtml(Model model) {
        return "process_price/add_produce";
    }


    @RequestMapping("/updateProduceHtml")
    public String updateProduceHtml(Model model,String id) {
        model.addAttribute("id", id);
        return "process_price/update_produce";
    }

    @RequestMapping("/info_produce")
    @ResponseBody
    public Object info_produce(String id) {
        return iProcessPriceProduceService.getById(id);
    }

    @PostMapping("/list_type")
    @ResponseBody
    public LayTableR list_type(Integer page, Integer limit, String key) {
        QueryWrapper<ProcessPriceOrder> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(key)){
            queryWrapper.eq("type", key);
        }
        Page<ProcessPriceOrder> priceOrderPage = iProcessPriceOrderService.listType(new Page<>(page, limit), queryWrapper);
        return LayTableR.result(0,priceOrderPage.getTotal(), priceOrderPage.getRecords());
    }

    @RequestMapping("/list_order")
    @ResponseBody
    public LayTableR list_order(Integer page, Integer limit, String master) throws Exception{
        QueryWrapper<ProcessPriceOrder> ew = ConditionUtil.convert(master, new QueryWrapper<>());
        Page<ProcessPriceOrder> pageList = iProcessPriceOrderService.page(new Page<>(page, limit), ew);
        List<Map<String, String>> result = new ArrayList<>();
        for(ProcessPriceOrder processPriceOrder : pageList.getRecords()){
            Map<String, String> map = BeanUtils.describe(processPriceOrder);
            map.put("customerName", iCustomerService.getOne(new LambdaQueryWrapper<Customer>().eq(Customer::getCode,processPriceOrder.getCustomerId())).getName());
            map.put("productName", iProductService.getOne(new LambdaQueryWrapper<Product>().eq(Product::getCode,processPriceOrder.getProductId())).getName());
            map.put("orderProcessName", iProcessService.getOne(new LambdaQueryWrapper<Process>().eq(Process::getCode,processPriceOrder.getOrderProcessCode())).getName());
            map.put("createUserName", iSysUserService.getById(processPriceOrder.getCreateUser()).getUserName());
            result.add(map);
        }
        return LayTableR.result(0, pageList.getTotal(), result);
    }

    @RequestMapping("/list_produce")
    @ResponseBody
    public LayTableR list_produce(Long orderId) throws Exception{
        List<ProcessPriceProduce> list = iProcessPriceProduceService.list(new QueryWrapper<ProcessPriceProduce>().eq("order_id", orderId));
        List<Map<String, String>> result = new ArrayList<>();
        for(ProcessPriceProduce processPriceProduce : list){
            Map<String, String> map = BeanUtils.describe(processPriceProduce);
            map.put("customerName", iCustomerService.getOne(new LambdaQueryWrapper<Customer>().eq(Customer::getCode,processPriceProduce.getCustomerId())).getName());
            map.put("productName", iProductService.getOne(new LambdaQueryWrapper<Product>().eq(Product::getCode,processPriceProduce.getProductId())).getName());
            map.put("produceProcessName", iProcessService.getOne(new LambdaQueryWrapper<Process>().eq(Process::getCode,processPriceProduce.getProduceProcessCode())).getName());
            map.put("createUserName", iSysUserService.getById(processPriceProduce.getCreateUser()).getUserName());
            result.add(map);
        }
        return LayTableR.result(0, list.size(), result);
    }

    @PostMapping("/add_order")
    @ResponseBody
    public R add_order(ProcessPriceOrder processPriceOrder) {
        try {
            ProcessPriceOrder order = iProcessPriceOrderService.getOne(new LambdaQueryWrapper<ProcessPriceOrder>()
                    .eq(ProcessPriceOrder::getCustomerId, processPriceOrder.getCustomerId())
                    .eq(ProcessPriceOrder::getProductId, processPriceOrder.getProductId())
                    .eq(ProcessPriceOrder::getType, processPriceOrder.getType())
                    .eq(ProcessPriceOrder::getOrderProcessCode, processPriceOrder.getOrderProcessCode()));
            if(order != null) {
                return R.error("数据已存在，请勿重复添加");
            }
            processPriceOrder.setCreateUser(ShiroUtil.getUserId());
            processPriceOrder.setCreateTime(new Date());
            iProcessPriceOrderService.save(processPriceOrder);
        } catch (Exception e) {
            e.printStackTrace();
            return R.error("系统异常");
        }
        return R.ok();
    }

    @PostMapping("/update_order")
    @ResponseBody
    public R update_order(ProcessPriceOrder processPriceOrder) {
        try {
            ProcessPriceOrder order = iProcessPriceOrderService.getOne(new LambdaQueryWrapper<ProcessPriceOrder>()
                    .eq(ProcessPriceOrder::getCustomerId, processPriceOrder.getCustomerId())
                    .eq(ProcessPriceOrder::getProductId, processPriceOrder.getProductId())
                    .eq(ProcessPriceOrder::getType, processPriceOrder.getType())
                    .eq(ProcessPriceOrder::getOrderProcessCode, processPriceOrder.getOrderProcessCode()));
            if(order != null && !processPriceOrder.getId().equals(order.getId())) {
                return R.error("数据已存在");
            }
            iProcessPriceOrderService.updateById(processPriceOrder);
        } catch (Exception e) {
            return R.error("系统异常");
        }
        return R.ok();
    }

    @PostMapping("/delete_order")
    @ResponseBody
    public R delete_order(@RequestBody List<String> ids) {
        try {
            iProcessPriceOrderService.deleteInfo(ids);
        } catch (Exception e) {
            return R.error("系统异常");
        }
        return R.ok();
    }

    @PostMapping("/add_produce")
    @ResponseBody
    public R add_produce(ProcessPriceProduce processPriceProduce) {
        try {
            ProcessPriceProduce produce = iProcessPriceProduceService.getOne(new LambdaQueryWrapper<ProcessPriceProduce>()
                    .eq(ProcessPriceProduce::getOrderId, processPriceProduce.getOrderId())
                    .eq(ProcessPriceProduce::getProduceProcessCode, processPriceProduce.getProduceProcessCode()));
            if(produce != null) {
                return R.error("数据已存在，请勿重复添加");
            }
            ProcessPriceOrder order = iProcessPriceOrderService.getById(processPriceProduce.getOrderId());
            processPriceProduce.setCustomerId(order.getCustomerId());
            processPriceProduce.setProductId(order.getProductId());
            processPriceProduce.setType(order.getType());
            processPriceProduce.setPricingMethod(order.getPricingMethod());
            processPriceProduce.setCreateUser(ShiroUtil.getUserId());
            processPriceProduce.setCreateTime(new Date());
            iProcessPriceProduceService.save(processPriceProduce);
        } catch (Exception e) {
            return R.error("系统异常");
        }
        return R.ok();
    }

    @PostMapping("/update_produce")
    @ResponseBody
    public R update_produce(ProcessPriceProduce processPriceProduce) {
        try {
            ProcessPriceProduce produce = iProcessPriceProduceService.getOne(new LambdaQueryWrapper<ProcessPriceProduce>()
                    .eq(ProcessPriceProduce::getOrderId, processPriceProduce.getOrderId())
                    .eq(ProcessPriceProduce::getProduceProcessCode, processPriceProduce.getProduceProcessCode()));
            if(produce != null && produce.getId() != processPriceProduce.getId()) {
                return R.error("数据已存在");
            }
            iProcessPriceProduceService.updateById(processPriceProduce);
        } catch (Exception e) {
            return R.error("系统异常");
        }
        return R.ok();
    }

    @PostMapping("/delete_produce")
    @ResponseBody
    public R delete_produce(@RequestBody List<String> ids) {
        try {
            iProcessPriceProduceService.removeBatchByIds(ids);
        } catch (Exception e) {
            return R.error("系统异常");
        }
        return R.ok();
    }
    @RequestMapping("/upload")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public R upload(String data) {
        String msg="";
        boolean s=false;// 这组数据是否有错
        try {
            // 转换为数组
            List<Map> list = JSON.parseArray(data, Map.class);
            for (int i = 0; i <list.size() ; i++) {
                boolean f=false;// 当前数据是否出错
                ProcessPriceOrder processPriceOrder = JSON.parseObject(JSON.toJSONString(list.get(i)), ProcessPriceOrder.class);
                // 校验数据
                // 校验客户编码
                LambdaQueryWrapper<Customer> cq = new LambdaQueryWrapper<>();
                cq.eq(Customer::getCode,processPriceOrder.getCustomerId());
                Customer customer = iCustomerService.getOne(cq);
                if (customer==null){
                    f=true;
                    msg+="本地没有"+"第"+(i+1)+"条数据的客户编码";
                }
                // 校验产品编码
                LambdaQueryWrapper<Product> pq = new LambdaQueryWrapper<>();
                pq.eq(Product::getCode,processPriceOrder.getProductId());
                Product product = iProductService.getOne(pq);
                if (product==null){
                    f=true;
                    msg+="-本地没有"+"第"+(i+1)+"条数据的产品编码";
                }
                // 校验计价方式
//                String type = processPriceOrder.getPricingMethod();
//                type=type.replaceAll(" ","");
//                if (!type.equals("计时") && !type.equals("计件") ){
//                    f=true;
//                    msg+="-第"+(i+1)+"条数据的计价方式不属于计件或者计时";
//                }
                // 校验订单工序
                LambdaQueryWrapper<Process> prq = new LambdaQueryWrapper<>();
                prq.eq(Process::getCode,processPriceOrder.getOrderProcessCode());
                Process one = iProcessService.getOne(prq);
                if (one==null){
                    f=true;
                    msg+="-本地没有"+"第"+(i+1)+"条数据的订单工序";
                }
                if (f){
                    msg+="\n\t";
                    s=true;
                    continue;
                }
                LambdaQueryWrapper<ProcessPriceOrder> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(ProcessPriceOrder::getCustomerId,processPriceOrder.getCustomerId())
                        .eq(ProcessPriceOrder::getProductId,processPriceOrder.getProductId())
                        .eq(ProcessPriceOrder::getType,processPriceOrder.getType())
                        .eq(ProcessPriceOrder::getPricingMethod, processPriceOrder.getPricingMethod())
                        .eq(ProcessPriceOrder::getOrderProcessCode,processPriceOrder.getOrderProcessCode());
                ProcessPriceOrder list1 = iProcessPriceOrderService.getOne(wrapper);
                if (list1==null){
                    processPriceOrder.setCreateUser(ShiroUtil.getUserId());
                    processPriceOrder.setCreateTime(new Date());
                    iProcessPriceOrderService.save(processPriceOrder);
                }else {
                    processPriceOrder.setId(list1.getId());
                    processPriceOrder.setCreateUser(list1.getCreateUser());
                    processPriceOrder.setCreateTime(list1.getCreateTime());
                   iProcessPriceOrderService.updateById(processPriceOrder);
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
            return R.error("系统异常");
        }
        if (s){
            return R.error(msg);
        }
        return R.ok();
    }

    @RequestMapping("/download")
    @ResponseBody
    public void download(String condition, HttpServletResponse response) {
        List<Map> conditionList = JSON.parseArray(condition, Map.class);
        try {
            String queryCriteriaStr = "【查询条件】";
            QueryWrapper qw = new QueryWrapper();
            if(conditionList.size() > 0){
                for(Map m : conditionList){
                    queryCriteriaStr = queryCriteriaStr+m.get("title")+": "+m.get("value")+";   ";
                    switch (m.get("type").toString()){
                        case "equal":
                            qw.eq(m.get("field").toString(), m.get("value"));
                            break;
                        case "like":
                            qw.like(m.get("field").toString(), m.get("value"));
                            break;
                        case "unequal":
                            qw.ne(m.get("field").toString(), m.get("value"));
                            break;
                        case "empty":
                            qw.isNull(m.get("field").toString());
                            break;
                        case "notempty":
                            qw.isNotNull(m.get("field").toString());
                            break;
                        case "between":
                            qw.between(m.get("field").toString(), m.get("left"), m.get("right"));
                            break;
                        case "greater_than":
                            qw.gt(m.get("field").toString(), m.get("value"));
                            break;
                        case "less_than":
                            qw.lt(m.get("field").toString(), m.get("value"));
                            break;
                        case "start":
                            qw.likeLeft(m.get("field").toString(), m.get("value"));
                            break;
                        case "end":
                            qw.likeRight(m.get("field").toString(), m.get("value"));
                            break;
                    }
                }
            }else{
                queryCriteriaStr = queryCriteriaStr+"无查询条件，查询全表";
            }
            //excel表头
            List<TitleEntity> titleList=new ArrayList<>();
            titleList.add(new TitleEntity("0",null,"客户工序价格对照表",null));
            titleList.add(new TitleEntity("1","0",queryCriteriaStr,null));
            titleList.add(new TitleEntity("2","1","客户编码","customer_id"));
            titleList.add(new TitleEntity("3","1","客户名称","customer_name"));
            titleList.add(new TitleEntity("4","1","产品编码","product_id"));
            titleList.add(new TitleEntity("5","1","产品名称","product_name"));
            titleList.add(new TitleEntity("6","1","类型","type"));
            titleList.add(new TitleEntity("7","1","计价方式","pricing_method"));
            titleList.add(new TitleEntity("8","1","标准工时","expect_hours"));
            titleList.add(new TitleEntity("9","1","工序编码","order_process_code"));
            titleList.add(new TitleEntity("10","1","工序名称","order_process_name"));
            titleList.add(new TitleEntity("11","1","工序单价","order_price"));
            //excel数据
            List<Map<String,Object>> list = iProcessPriceOrderService.getSaleReportList(qw);
            ExcelTool excelTool = new ExcelTool("客户工序价格对照表",20,20);
            List<Column>  titleData = excelTool.columnTransformer(titleList,"t_id","t_pid","t_content","t_fielName","0");
            response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode("客户工序价格对照表"+ DateUtil.currentYYMMDD()+".xlsx", "utf-8"));
            excelTool.exportExcel(titleData,list, response.getOutputStream(),true,true);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

